package org.gap.wizards.pc;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.gap.jseed.injection.annotation.Singleton;
import org.gap.wizards.creature.BaseCreature;
import org.gap.wizards.creature.Creature;
import org.gap.wizards.creature.Description;
import org.gap.wizards.items.Inventory;
import org.gap.wizards.items.Item;
import org.gap.wizards.quest.Quest;
import org.gap.wizards.spells.Spell;
import org.gap.wizards.utils.FlatFilePersistence;
import org.gap.wizards.views.ViewPlatform.Color;
import org.gap.wizards.world.Location;

@Singleton
public class Player extends BaseCreature implements PlayerCharacter {
	private SpellBook spellBook;
	private Inventory inventory;
	private Map<String, Skill> skills;
	private List<Quest> quests;

	public Player() {
		super(new Description(Color.WHITE, "@", "Player"));
		spellBook = new SpellBook();
		inventory = new Inventory();
		skills = new HashMap<String, Skill>();
		quests = new ArrayList<Quest>();
		
		initAttribute(Attribute.Hitpoints, 15, 10);
		initAttribute(Attribute.ManaPoints, 15, 15);
	}

	@Override
	public void addItem(Item toAdd) {
		inventory.addItem(toAdd);
	}
	
	@Override
	public void removeItem(Item toRemove) {
		inventory.removeItem(toRemove);
	}

	@Override
	public Inventory getInventory() {
		return inventory;
	}
	
	@Override
	public SpellBook getSpellBook() {
		return spellBook;
	}
	
	@Override
	public void learnSpell(Spell spell) {
		spellBook.addSpell(spell);
	}

	@Override
	public Skill getSkill(String string) {
		return skills.get(string);
	}

	@Override
	public void addSkill(Skill skill) {
		skills.put(skill.getName(), skill);
	}

	@Override
	public Collection<Item> dropAllItems() {
		return null;
	}
	
	@Override
	public void addQuest(Quest quest) {
		quests.add(quest);
	}
	
	@Override
	public List<Quest> getFinishedQuests() {
		List<Quest> result = new ArrayList<Quest>();
		for (Quest each : quests) {
			if (each.isCompleted(this)) {
				result.add(each);
			}
		}
		return result;
	}

	@Override
	public void attack(Creature pc) {
		
	}
	
	@Override
	public void update(Location location) {
		// maybe used to handle bleeding, healing, food, etc.
	}

	@Override
	public void persist() {
		try {
			FlatFilePersistence persistence = new FlatFilePersistence(false, "player", "wizard", "save");
			super.persist(persistence);
			inventory.persist(persistence);
			persistence.save();
		} catch (IOException ioe) {
			throw new RuntimeException("Failed to save player", ioe);
		}
	}

	@Override
	public void load() {
		try {
			FlatFilePersistence persistence = new FlatFilePersistence(false, "player", "wizard", "save");
			super.load(persistence);
			inventory.load(persistence);
		} catch (IOException e) {
			throw new RuntimeException("Unable to load player data", e);
		}
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (obj.getClass().equals(Player.class)) {
			Player other = (Player) obj;
			return inventory.equals(other.getInventory()) && super.equals(other);
		}
		return false;
	}
}
